<template>
  <div class="watermark-container" ref="parentRef">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'waterMark',
  props: {
    waterMarkImg: {
      type: String,
      default: ''
    },
    text: {
      type: String,
      default: '禁止下载'
    },
    textColor: {
      type: String,
      default: '#999'
    },
    fontSize: {
      type: [Number, String],
      default: 18
    },
    gap: {
      type: [Number, String],
      default: 20
    },
    rotate: {
      type: [Number, String],
      default: -15
    },
    opacity: {
      type: [Number, String],
      default: 0.7
    },
    zIndex: {
      type: [Number, String],
      default: 9999
    },
    repeat: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      watermarkDom: null,
      ob: null
    };
  },
  computed: {
    useWatermarkBg() {
      const canvas = document.createElement('canvas');
      const devicePixelRatio = window.devicePixelRatio || 1;
      // 设置字体大小
      const fontSize = this.fontSize * devicePixelRatio;
      const font = fontSize + 'px serif';
      const ctx = canvas.getContext('2d');
      // 获取文字宽度
      ctx.font = font;
      const { width } = ctx.measureText(this.text);
      const canvasSize = Math.max(100, width) + this.gap * devicePixelRatio;
      canvas.width = canvasSize;
      canvas.height = canvasSize;
      ctx.translate(canvas.width / 2, canvas.height / 2);
      // 旋转 45 度让文字变倾斜
      ctx.rotate((Math.PI / 180) * this.rotate);
      ctx.fillStyle = `${this.textColor}`;
      ctx.globalAlpha = `${this.opacity}`;
      ctx.font = font;
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      // 将文字画出来
      ctx.fillText(this.text, 0, 0);
      return {
        base64: this.waterMarkImg || canvas.toDataURL(),
        size: canvasSize,
        styleSize: canvasSize / devicePixelRatio
      };
    }
  },
  mounted() {
    this.createWatermark();
    this.ob = new MutationObserver((entries) => {
      for (let entry of entries) {
        // 处理被删除的情况
        for (let node of entry.removedNodes) {
          if (node === this.watermarkDom) {
            this.createWatermark();
          }
        }
        // 处理被修改的情况
        if (entry.type === 'attributes' && entry.target === this.watermarkDom) {
          this.createWatermark();
        }
      }
    });
    this.ob.observe(this.$refs.parentRef, {
      attributes: true,
      childList: true,
      subtree: true
    });
  },
  beforeDestroy() {
    this.ob.disconnect();
  },
  methods: {
    createWatermark() {
      let parentRef = this.$refs.parentRef;
      if (!parentRef) {
        return;
      }
      if (this.watermarkDom) {
        this.watermarkDom.remove();
        this.watermarkDom = null;
      }
      let { base64, styleSize } = this.useWatermarkBg;
      this.watermarkDom = document.createElement('div');
      this.watermarkDom.style.position = 'absolute';
      this.watermarkDom.style.backgroundImage = `url(${base64})`;
      this.watermarkDom.style.backgroundRepeat = this.repeat ? 'repeat' : 'no-repeat';
      this.watermarkDom.style.backgroundPosition = 'center center';
      this.watermarkDom.style.backgroundSize = `${styleSize}px ${styleSize}px`;
      this.watermarkDom.style.pointerEvents = 'none';
      this.watermarkDom.style.top = 0;
      this.watermarkDom.style.right = 0;
      this.watermarkDom.style.bottom = 0;
      this.watermarkDom.style.left = 0;
      this.watermarkDom.style.zIndex = this.zIndex;
      parentRef.appendChild(this.watermarkDom);
    }
  }
};
</script>

<style lang="scss" scoped>
.watermark-container {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 100%;
}
</style>
